/*
 * JVM_OpcodeMath.c
 *
 *  Created on: 04.01.2011
 *      Author: Tavin
 */

//Test Console Output
#include <stdint.h>

#include "Console.h"

#include "JVM_Opcode.h"
#include "JVM_OpcodeMath.h"
#include "JVM_StatusCodes.h"



/****************************************************************************************/
/*																						*/
/*	Function : JVM_cmd_iinc									Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.12			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JVM_cmd_iinc()
{
	uint8_t index;
	int8_t constant;
	uint32_t value;

	index=JVM_Opcode_getCodeByte();
	constant=JVM_Opcode_getCodeByte();

	value=JVM_Opcode_getIntVar(index);
	value+=constant;
	JVM_Opcode_setIntVar(index,value);

	/*int32_t tmpValue1;
	int32_t tmpValue2;


	tmpValue1=JVM_Opcode_popIntValue();

	JVM_Opcode_pushIntValue(tmpValue1+tmpValue2);
*/
	return(STCD_OK);
}

/****************************************************************************************/
/*																						*/
/*	Function : JVM_cmd_iadd									Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.4			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JVM_cmd_iinc_w()
{

	return(STCD_OK);
}

/****************************************************************************************/
/*																						*/
/*	Function : JVM_cmd_iadd									Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.4			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JVM_cmd_iadd()
{
	int32_t tmpValue1;
	int32_t tmpValue2;

	tmpValue2=JVM_Opcode_popIntValue();
	tmpValue1=JVM_Opcode_popIntValue();

	JVM_Opcode_pushIntValue(tmpValue1+tmpValue2);

	return(STCD_OK);
}

/****************************************************************************************/
/*																						*/
/*	Function : JVM_cmd_isub									Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.4			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JVM_cmd_isub()
{
	int32_t tmpValue1;
	int32_t tmpValue2;

	tmpValue2=JVM_Opcode_popIntValue();
	tmpValue1=JVM_Opcode_popIntValue();

	JVM_Opcode_pushIntValue(tmpValue1-tmpValue2);

	return(STCD_OK);
}


/****************************************************************************************/
/*																						*/
/*	Function : JVM_cmd_imul									Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.4			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JVM_cmd_imul()
{
	int32_t tmpValue1;
	int32_t tmpValue2;

	tmpValue2=JVM_Opcode_popIntValue();
	tmpValue1=JVM_Opcode_popIntValue();

	JVM_Opcode_pushIntValue(tmpValue1*tmpValue2);

	return(STCD_OK);
}

/****************************************************************************************/
/*																						*/
/*	Function : JVM_cmd_idiv									Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.4			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JVM_cmd_idiv()
{
	int32_t tmpValue1;
	int32_t tmpValue2;

	tmpValue2=JVM_Opcode_popIntValue();
	tmpValue1=JVM_Opcode_popIntValue();

	//Throw Arithmetic Exception,
	if(tmpValue2 == 0) {
		return STCD_ARITHMETIC_EXCEPTION;
	}

	JVM_Opcode_pushIntValue(tmpValue1/tmpValue2);

	return(STCD_OK);
}


/************************** Long ************************************/



/****************************************************************************************/
/*																						*/
/*	Function : JVM_cmd_ladd									Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.5			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JVM_cmd_ladd()
{
	int64_t tmpValue1;
	int64_t tmpValue2;

	tmpValue2=JVM_Opcode_popLongValue();
	tmpValue1=JVM_Opcode_popLongValue();

	JVM_Opcode_pushLongValue(tmpValue1+tmpValue2);

	return(STCD_OK);
}

/****************************************************************************************/
/*																						*/
/*	Function : JVM_cmd_lsub									Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.5			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JVM_cmd_lsub()
{
	int64_t tmpValue1;
	int64_t tmpValue2;

	tmpValue2=JVM_Opcode_popLongValue();
	tmpValue1=JVM_Opcode_popLongValue();

	JVM_Opcode_pushLongValue(tmpValue1-tmpValue2);

	return(STCD_OK);
}


/****************************************************************************************/
/*																						*/
/*	Function : JVM_cmd_lmul									Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.5			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JVM_cmd_lmul()
{
	int64_t tmpValue1;
	int64_t tmpValue2;

	tmpValue2=JVM_Opcode_popLongValue();
	tmpValue1=JVM_Opcode_popLongValue();

	JVM_Opcode_pushLongValue(tmpValue1*tmpValue2);

	return(STCD_OK);
}

/****************************************************************************************/
/*																						*/
/*	Function : JVM_cmd_ldiv									Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.5			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JVM_cmd_ldiv()
{
	int64_t tmpValue1;
	int64_t tmpValue2;

	tmpValue2=JVM_Opcode_popLongValue();
	tmpValue1=JVM_Opcode_popLongValue();

	JVM_Opcode_pushLongValue(tmpValue1/tmpValue2);

	return(STCD_OK);
}


/************************** float ************************************/

/****************************************************************************************/
/*																						*/
/*	Function : JVM_cmd_fadd									Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.4			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JVM_cmd_fadd()
{
	float tmpValue1;
	float tmpValue2;

	tmpValue2=JVM_Opcode_popFloatValue();
	tmpValue1=JVM_Opcode_popFloatValue();

	JVM_Opcode_pushFloatValue(tmpValue1+tmpValue2);

	return(STCD_OK);
}

/****************************************************************************************/
/*																						*/
/*	Function : JVM_cmd_fsub									Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.4			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JVM_cmd_fsub()
{
	float tmpValue1;
	float tmpValue2;

	tmpValue2=JVM_Opcode_popFloatValue();
	tmpValue1=JVM_Opcode_popFloatValue();

	JVM_Opcode_pushFloatValue(tmpValue1-tmpValue2);

	return(STCD_OK);
}


/****************************************************************************************/
/*																						*/
/*	Function : JVM_cmd_fmul									Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.4			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JVM_cmd_fmul()
{
	float tmpValue1;
	float tmpValue2;

	tmpValue2=JVM_Opcode_popFloatValue();
	tmpValue1=JVM_Opcode_popFloatValue();

	JVM_Opcode_pushFloatValue(tmpValue1*tmpValue2);

	return(STCD_OK);
}

/****************************************************************************************/
/*																						*/
/*	Function : JVM_cmd_fdiv									Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.4			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JVM_cmd_fdiv()
{
	float tmpValue1;
	float tmpValue2;

	tmpValue2=JVM_Opcode_popFloatValue();
	tmpValue1=JVM_Opcode_popFloatValue();

	JVM_Opcode_pushFloatValue(tmpValue1/tmpValue2);

	return(STCD_OK);
}

/************************** double ************************************/

/****************************************************************************************/
/*																						*/
/*	Function : JVM_cmd_dadd									Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.5			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JVM_cmd_dadd()
{
	double tmpValue1;
	double tmpValue2;

	tmpValue2=JVM_Opcode_popDoubleValue();
	tmpValue1=JVM_Opcode_popDoubleValue();

	JVM_Opcode_pushDoubleValue(tmpValue1+tmpValue2);

	return(STCD_OK);
}

/****************************************************************************************/
/*																						*/
/*	Function : JVM_cmd_dsub									Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.5			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JVM_cmd_dsub()
{
	double tmpValue1;
	double tmpValue2;

	tmpValue2=JVM_Opcode_popDoubleValue();
	tmpValue1=JVM_Opcode_popDoubleValue();

	JVM_Opcode_pushDoubleValue(tmpValue1-tmpValue2);

	return(STCD_OK);
}


/****************************************************************************************/
/*																						*/
/*	Function : JVM_cmd_dmul									Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.5			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JVM_cmd_dmul()
{
	double tmpValue1;
	double tmpValue2;

	tmpValue2=JVM_Opcode_popDoubleValue();
	tmpValue1=JVM_Opcode_popDoubleValue();

	JVM_Opcode_pushDoubleValue(tmpValue1*tmpValue2);

	return(STCD_OK);
}

/****************************************************************************************/
/*																						*/
/*	Function : JVM_cmd_ddiv									Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.5			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JVM_cmd_ddiv()
{
	double tmpValue1;
	double tmpValue2;

	tmpValue2=JVM_Opcode_popDoubleValue();
	tmpValue1=JVM_Opcode_popDoubleValue();

	JVM_Opcode_pushDoubleValue(tmpValue1/tmpValue2);

	return(STCD_OK);
}






/****************************************************************************************/
/*																						*/
/*	Function : JVM_cmd_irem									Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.5			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JVM_cmd_irem()
{
	int32_t tmpValue1;
	int32_t tmpValue2;
	int32_t remainder;

	tmpValue2=JVM_Opcode_popIntValue();
	tmpValue1=JVM_Opcode_popIntValue();

	//remainder=((tmpValue1-tmpValue2)*tmpValue2) + (tmpValue1%tmpValue2);
	remainder=tmpValue1-((tmpValue1/tmpValue2)*tmpValue2);

	JVM_Opcode_pushIntValue(remainder);

	return(STCD_OK);
}
/****************************************************************************************/
/*																						*/
/*	Function : JVM_cmd_lrem									Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.5			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JVM_cmd_lrem()
{
	int64_t tmpValue1;
	int64_t tmpValue2;
	int64_t remainder;

	tmpValue2=JVM_Opcode_popLongValue();
	tmpValue1=JVM_Opcode_popLongValue();

	//remainder=((tmpValue1/tmpValue2)*tmpValue2) + (tmpValue1%tmpValue2);
	remainder=tmpValue1-((tmpValue1/tmpValue2)*tmpValue2);
	JVM_Opcode_pushLongValue(remainder);

	return(STCD_OK);
}
/****************************************************************************************/
/*																						*/
/*	Function : JVM_cmd_frem									Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.5			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JVM_cmd_frem(){
	return(STCD_OK);
}
/****************************************************************************************/
/*																						*/
/*	Function : JVM_cmd_drem									Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.5			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JVM_cmd_drem()
{
/*	double tmpValue1;
	double tmpValue2;
	double remainder;

	tmpValue2=JVM_Opcode_popDoubleValue();
	tmpValue1=JVM_Opcode_popDoubleValue();

	remainder=(((uint64_t)(tmpValue1/tmpValue2))*tmpValue2) + (tmpValue1 mod tmpValue2);

	JVM_Opcode_pushDoubleValue(tmpValue1/tmpValue2);
*/
	return(STCD_OK);

}



/****************************************************************************************/
/*																						*/
/*	Function : JVM_cmd_ineg									Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.5			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JVM_cmd_ineg()
{
	int32_t tmpValue;

	tmpValue=JVM_Opcode_popIntValue();

	tmpValue*=-1;

	JVM_Opcode_pushIntValue(tmpValue);
	return(STCD_OK);
}
/****************************************************************************************/
/*																						*/
/*	Function : JVM_cmd_lneg									Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.5			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JVM_cmd_lneg()
{
	uint64_t tmpValue;

	tmpValue=JVM_Opcode_popLongValue();

	tmpValue*=-1;

	JVM_Opcode_pushLongValue(tmpValue);
	return(STCD_OK);
}
/****************************************************************************************/
/*																						*/
/*	Function : JVM_cmd_fneg									Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.5			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JVM_cmd_fneg()
{
	float tmpValue;

	tmpValue=JVM_Opcode_popFloatValue();

	tmpValue*=-1;

	JVM_Opcode_pushFloatValue(tmpValue);
	return(STCD_OK);
}
/****************************************************************************************/
/*																						*/
/*	Function : JVM_cmd_dneg									Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.5			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JVM_cmd_dneg()
{
	double tmpValue;

	tmpValue=JVM_Opcode_popDoubleValue();

	tmpValue*=-1;

	JVM_Opcode_pushDoubleValue(tmpValue);
	return(STCD_OK);
}


